﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace RMS.Common.Error
{
    public static class ExceptionExtend
    {
        /// <summary>
        /// 获取最内层异常提示
        /// </summary>
        /// <param name="error">Exception异常类</param>
        /// <returns></returns>
        public static string GetInnerMessage(this Exception error)
        {
            if (error == null)
            {
                return string.Empty;
            }
            if (error.InnerException == null)
            {
                return error.Message;
            }
            return error.GetInnerMessage();
        }
        /// <summary>
        /// 转换类型为含有Http访问信息的ErrorLog模型
        /// </summary>
        /// <param name="error">异常信息</param>
        /// <returns></returns>
        public static ErrorLog ToHttpErrorLog(this Exception error)
        {
            ErrorLog log = new ErrorLog();
            log.ProjectName = ConfigHelper.GetAppValue("AppName", "Null");
            log.Error = JsonConvert.SerializeObject(error);
            log.Message = error.Message;
            log.Url = HttpContext.Current.Request.Url == null ? string.Empty : HttpContext.Current.Request.Url.ToString();//错误发生地址
            log.UrlReferrer = HttpContext.Current.Request.UrlReferrer == null ? string.Empty : HttpContext.Current.Request.UrlReferrer.ToString();//来源链接
            log.UrlContentType = HttpContext.Current.Request.ContentType;
            #region 访问参数
            if (log.UrlContentType == "application/json")
            {
                HttpContext.Current.Request.InputStream.Position = 0;
                StreamReader sr = new StreamReader(HttpContext.Current.Request.InputStream);
                log.UrlParameter = sr.ReadToEnd();
            }
            else
            {
                log.UrlParameter = HttpContext.Current.Request.Form.ToString();
            } 
            #endregion
            #region 客户端IP地址
            //if (!string.IsNullOrWhiteSpace(HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]))
            //    log.ClientIP = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
            //else
            //    log.ClientIP = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
            //if (string.IsNullOrWhiteSpace(log.ClientIP))
            //    log.ClientIP = HttpContext.Current.Request.UserHostAddress;
            log.ClientIP = HttpHelper.GetRealIP();
            #endregion
            return log;
        }
        /// <summary>
        /// 保存错误日志
        /// </summary>
        /// <param name="log"></param>
        public static void Save(this ErrorLog log)
        {
            var logtype = ConfigHelper.GetAppValue("LogType");
            switch (logtype)
            {
                case "MongoDB":
                    MongoDBHelper.InsertOne<ErrorLog>(log);
                    break;
                default:
                    NLogHelper nlog = new NLogHelper();
                    nlog.Error("ERRORLOG:" + JsonConvert.SerializeObject(log));
                    break;
            }
        }
        /// <summary>
        /// 保存异常错误日志是发生新的异常将新的异常使用nlog记录到文件中
        /// </summary>
        /// <param name="e">记录异常日志时发生的异常</param>
        public static void SaveLogException(this Exception e)
        {
            NLogHelper nlog = new NLogHelper();
            try
            {
                nlog.Fatal(JsonConvert.SerializeObject(e));
                var url = HttpContext.Current.Request.Url == null ? string.Empty : HttpContext.Current.Request.Url.ToString();//错误发生地址
                var urlReferrer = HttpContext.Current.Request.UrlReferrer == null ? string.Empty : HttpContext.Current.Request.UrlReferrer.ToString();//来源链接
                var urlContentType = HttpContext.Current.Request.ContentType;
                nlog.Error("ERROR:\r\nUrl:" + url + "\r\nUrlReferrer" + urlReferrer + "\r\nContentType:" + urlContentType);
                if (urlContentType == "application/json")
                {
                    HttpContext.Current.Request.InputStream.Position = 0;
                    StreamReader sr = new StreamReader(HttpContext.Current.Request.InputStream);
                    nlog.Error(sr.ReadToEnd());
                }
                else
                {
                    nlog.Error(HttpContext.Current.Request.Form.ToString());
                }
            }
            catch (Exception)
            {
            }
        }
    }
}
